package com.agent.platform.client;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.List;
import java.util.Map;

/**
 * 工具管理器客户端 - 对应Node.js版本的ToolManager接口
 */
@Slf4j
@Component
public class ToolManagerClient {

    private final WebClient webClient;

    public ToolManagerClient(WebClient.Builder webClientBuilder) {
        this.webClient = webClientBuilder.build();
    }

    /**
     * 获取可用工具
     */
    public Mono<GetToolsResponse> getTools(
        String toolManagerUrl,
        String sessionId,
        String agentId,
        Map<String, Object> filters
    ) {
        GetToolsRequest request = new GetToolsRequest();
        request.setSessionId(sessionId);
        request.setAgentId(agentId);
        request.setFilters(filters);

        return webClient.post()
            .uri(toolManagerUrl + "/tools/get")
            .bodyValue(request)
            .retrieve()
            .bodyToMono(GetToolsResponse.class)
            .timeout(Duration.ofSeconds(10))
            .doOnError(e -> log.error("Failed to get tools from tool manager", e));
    }

    /**
     * 执行工具
     */
    public Mono<ExecuteToolResponse> executeTool(
        String toolManagerUrl,
        String sessionId,
        String agentId,
        ToolCall toolCall,
        int timeout
    ) {
        ExecuteToolRequest request = new ExecuteToolRequest();
        request.setSessionId(sessionId);
        request.setAgentId(agentId);
        request.setToolCall(toolCall);
        request.setTimeout(timeout);

        return webClient.post()
            .uri(toolManagerUrl + "/tools/execute")
            .bodyValue(request)
            .retrieve()
            .bodyToMono(ExecuteToolResponse.class)
            .timeout(Duration.ofMillis(timeout + 5000))
            .doOnError(e -> log.error("Failed to execute tool", e));
    }

    /**
     * 健康检查
     */
    public Mono<Boolean> healthCheck(String toolManagerUrl) {
        return webClient.get()
            .uri(toolManagerUrl + "/health")
            .retrieve()
            .bodyToMono(String.class)
            .map(response -> true)
            .timeout(Duration.ofSeconds(5))
            .onErrorReturn(false);
    }

    @Data
    public static class GetToolsRequest {
        private String sessionId;
        private String agentId;
        private Map<String, Object> filters;
    }

    @Data
    public static class GetToolsResponse {
        private String sessionId;
        private List<ToolDefinition> tools;
    }

    @Data
    public static class ToolDefinition {
        private String name;
        private String description;
        private Map<String, Object> parameters;
    }

    @Data
    public static class ExecuteToolRequest {
        private String sessionId;
        private String agentId;
        private ToolCall toolCall;
        private int timeout;
    }

    @Data
    public static class ExecuteToolResponse {
        private ToolResult result;
        private long executionTime;
    }

    @Data
    public static class ToolCall {
        private String id;
        private String type;
        private FunctionCall function;
    }

    @Data
    public static class FunctionCall {
        private String name;
        private String arguments;
    }

    @Data
    public static class ToolResult {
        private String id;
        private String result;
        private String error;
    }
}
